/**
 * 评论API库
 * @author HalRui
 * @version 1.0.0
 * @description 提供评论相关的业务逻辑功能，包括评论的创建、查询、更新、删除、点赞等操作
 * @date 2025年9月27日
 */

const Comments = require('../models/comments-model');
const UserInfos = require('../models/userinfos-model');
const Videos = require('../models/videos-model');
const { connectDB } = require('../utils/db');

/**
 * 创建评论
 * @param {Object} commentData - 评论数据
 * @param {number} commentData.userId - 用户ID
 * @param {number} commentData.videoID - 视频ID
 * @param {string} commentData.content - 评论内容
 * @param {number} [commentData.parentId=0] - 父评论ID，0表示顶级评论
 * @param {string} [commentData.ip] - 用户IP地址
 * @returns {Promise<Object>} 创建的评论信息
 */
async function createComment(commentData) {
    try {
        await connectDB();
        
        const { userId, videoID, content, parentId = 0, ip } = commentData;
        
        // 验证必要参数
        if (!userId || !videoID || !content) {
            throw new Error('用户ID、视频ID和评论内容不能为空');
        }
        
        // 验证用户是否存在
        const user = await UserInfos.findOne({ userId, isDeleted: false });
        if (!user) {
            throw new Error('用户不存在');
        }
        
        // 验证视频是否存在
        const video = await Videos.findOne({ videoID: videoID });
        if (!video) {
            throw new Error('视频不存在');
        }
        
        // 如果是回复评论，验证父评论是否存在
        if (parentId > 0) {
            const parentComment = await Comments.findOne({ 
                commentId: parentId, 
                isDeleted: false,
                status: 1
            });
            if (!parentComment) {
                throw new Error('父评论不存在');
            }
        }
        
        // 创建评论
        const result = await Comments.createComment({
            userId,
            videoID,
            content: content.trim(),
            parentId,
            ip: ip || ''
        });
        
        if (!result.success) {
            throw new Error(result.error || '创建评论失败');
        }
        
        // 获取评论详细信息（包含用户信息）
        const commentDetail = await getCommentDetail(result.comment.commentId);
        
        return commentDetail;
    } catch (error) {
        console.error('创建评论失败:', error);
        throw error;
    }
}

/**
 * 获取评论列表
 * @param {Object} options - 查询选项
 * @param {number} options.videoID - 视频ID
 * @param {number} [options.parentId=0] - 父评论ID，0表示获取顶级评论
 * @param {number} [options.page=1] - 页码
 * @param {number} [options.limit=20] - 每页数量
 * @param {string} [options.sortBy='createAt'] - 排序字段
 * @param {string} [options.sortOrder='desc'] - 排序方向
 * @returns {Promise<Object>} 评论列表和分页信息
 */
async function getCommentList(options) {
    try {
        await connectDB();
        
        const { 
            videoID, 
            parentId = 0, 
            page = 1, 
            limit = 20,
            sortBy = 'createAt',
            sortOrder = 'desc'
        } = options;
        
        if (!videoID) {
            throw new Error('视频ID不能为空');
        }
        
        // 获取评论列表
        const result = await Comments.findByVideoID(videoID, page, limit, parentId);
        
        // 获取用户信息
        const userIds = [...new Set(result.comments.map(comment => comment.userId))];
        const users = await UserInfos.find({ 
            userId: { $in: userIds }, 
            isDeleted: false 
        }).select('userId username avatar nickname').lean();
        
        const userMap = {};
        users.forEach(user => {
            userMap[user.userId] = user;
        });
        
        // 组合评论和用户信息
        const commentsWithUserInfo = result.comments.map(comment => {
            const user = userMap[comment.userId] || {};
            // 使用toObject()方法而不是getSafeJSON()
            const commentObj = comment.toObject ? comment.toObject() : comment;
            return {
                ...commentObj,
                user: {
                    userId: user.userId,
                    username: user.username || '',
                    nickname: user.nickname || '',
                    avatar: user.avatar || ''
                }
            };
        });
        
        return {
            comments: commentsWithUserInfo,
            pagination: result.pagination
        };
    } catch (error) {
        console.error('获取评论列表失败:', error);
        throw error;
    }
}

/**
 * 获取评论详情
 * @param {number} commentId - 评论ID
 * @returns {Promise<Object|null>} 评论详情
 */
async function getCommentDetail(commentId) {
    try {
        await connectDB();
        
        if (!commentId) {
            throw new Error('评论ID不能为空');
        }
        
        const comment = await Comments.findOne({ 
            commentId, 
            isDeleted: false
        }).lean();
        
        if (!comment) {
            return null;
        }
        
        // 暂时直接返回评论信息，不查询用户信息以避免超时
        return comment;
    } catch (error) {
        console.error('获取评论详情失败:', error);
        throw error;
    }
}

/**
 * 更新评论内容
 * @param {number} commentId - 评论ID
 * @param {number} userId - 用户ID
 * @param {string} content - 新的评论内容
 * @returns {Promise<Object>} 更新后的评论信息
 */
async function updateComment(commentId, userId, content) {
    try {
        await connectDB();
        
        if (!commentId || !userId || !content) {
            throw new Error('评论ID、用户ID和评论内容不能为空');
        }
        
        const comment = await Comments.findOne({ 
            commentId, 
            isDeleted: false,
            status: 1
        });
        
        if (!comment) {
            throw new Error('评论不存在');
        }
        
        if (comment.userId !== userId) {
            throw new Error('无权限修改此评论');
        }
        
        // 更新评论内容
        await comment.updateContent(content.trim());
        
        // 获取更新后的评论详情
        const updatedComment = await getCommentDetail(commentId);
        
        return updatedComment;
    } catch (error) {
        console.error('更新评论失败:', error);
        throw error;
    }
}

/**
 * 删除评论
 * @param {number} commentId - 评论ID
 * @param {number} userId - 用户ID
 * @returns {Promise<Object>} 删除结果
 */
async function deleteComment(commentId, userId) {
    try {
        await connectDB();
        
        if (!commentId || !userId) {
            throw new Error('评论ID和用户ID不能为空');
        }
        
        const comment = await Comments.findOne({ 
            commentId, 
            isDeleted: false 
        });
        
        if (!comment) {
            throw new Error('评论不存在');
        }
        
        if (comment.userId !== userId) {
            throw new Error('无权限删除此评论');
        }
        
        // 软删除评论
        await Comments.softDelete(commentId, userId);
        
        return { success: true, message: '评论删除成功' };
    } catch (error) {
        console.error('删除评论失败:', error);
        throw error;
    }
}

/**
 * 点赞评论
 * @param {number} commentId - 评论ID
 * @param {number} userId - 用户ID
 * @returns {Promise<Object>} 点赞结果
 */
async function likeComment(commentId, userId) {
    try {
        await connectDB();
        
        if (!commentId || !userId) {
            throw new Error('评论ID和用户ID不能为空');
        }
        
        // 验证评论是否存在
        const comment = await Comments.findOne({ 
            commentId, 
            isDeleted: false,
            status: 1
        });
        
        if (!comment) {
            throw new Error('评论不存在');
        }
        
        // 增加点赞数
        await Comments.increaseLike(commentId);
        
        // 获取更新后的评论信息
        const updatedComment = await getCommentDetail(commentId);
        
        return {
            success: true,
            message: '点赞成功',
            comment: updatedComment
        };
    } catch (error) {
        console.error('点赞评论失败:', error);
        throw error;
    }
}

/**
 * 点踩评论
 * @param {number} commentId - 评论ID
 * @param {number} userId - 用户ID
 * @returns {Promise<Object>} 点踩结果
 */
async function unlikeComment(commentId, userId) {
    try {
        await connectDB();
        
        if (!commentId || !userId) {
            throw new Error('评论ID和用户ID不能为空');
        }
        
        // 验证评论是否存在
        const comment = await Comments.findOne({ 
            commentId, 
            isDeleted: false,
            status: 1
        });
        
        if (!comment) {
            throw new Error('评论不存在');
        }
        
        // 增加点踩数
        await Comments.increaseUnlike(commentId);
        
        // 获取更新后的评论信息
        const updatedComment = await getCommentDetail(commentId);
        
        return {
            success: true,
            message: '点踩成功',
            comment: updatedComment
        };
    } catch (error) {
        console.error('点踩评论失败:', error);
        throw error;
    }
}

/**
 * 获取用户评论历史
 * @param {Object} options - 查询选项
 * @param {number} options.userId - 用户ID
 * @param {number} [options.page=1] - 页码
 * @param {number} [options.limit=20] - 每页数量
 * @returns {Promise<Object>} 用户评论历史
 */
async function getUserComments(options) {
    try {
        await connectDB();
        
        const { userId, page = 1, limit = 20 } = options;
        
        if (!userId) {
            throw new Error('用户ID不能为空');
        }
        
        // 获取用户评论列表
        const result = await Comments.findByUserId(userId, page, limit);
        
        // 获取视频信息
        const videoIds = [...new Set(result.comments.map(comment => comment.videoID))];
        const videos = await Videos.find({ 
            videoId: { $in: videoIds }, 
            isDeleted: false 
        }).select('videoId title coverImage').lean();
        
        const videoMap = {};
        videos.forEach(video => {
            videoMap[video.videoId] = video;
        });
        
        // 组合评论和视频信息
        const commentsWithVideoInfo = result.comments.map(comment => {
            const video = videoMap[comment.videoID] || {};
            return {
                ...comment.getSafeJSON(),
                video: {
                    videoId: video.videoId,
                    title: video.title || '',
                    coverImage: video.coverImage || ''
                }
            };
        });
        
        return {
            comments: commentsWithVideoInfo,
            pagination: result.pagination
        };
    } catch (error) {
        console.error('获取用户评论历史失败:', error);
        throw error;
    }
}

/**
 * 获取视频评论统计
 * @param {number} videoID - 视频ID
 * @returns {Promise<Object>} 评论统计信息
 */
async function getCommentStats(videoID) {
    try {
        await connectDB();
        
        if (!videoID) {
            throw new Error('视频ID不能为空');
        }
        
        const stats = await Comments.getCommentStats(videoID);
        
        return stats;
    } catch (error) {
        console.error('获取评论统计失败:', error);
        throw error;
    }
}

module.exports = {
    createComment,
    getCommentList,
    getCommentDetail,
    updateComment,
    deleteComment,
    likeComment,
    unlikeComment,
    getUserComments,
    getCommentStats
};